package p.ithorns.tools.translator.apt.handler;


import p.ithorns.tools.translator.annotation.*;
import p.ithorns.tools.translator.annotation.field.*;
import p.ithorns.tools.translator.apt.AbstractHandler;
import p.ithorns.tools.translator.apt.utils.AptUtil;
import p.ithorns.tools.translator.apt.model.AnnotateMeta;
import p.ithorns.tools.translator.apt.model.AnnotatedParam;

import java.util.*;

/**
 * DictMetaHandler
 *
 * @author HtL
 * @date 2024/6/11 8:41
 * @since 1.0.0
 */
public class DictMetaHandler extends AbstractHandler {

    @Override
    public AnnotateMeta rebuild(AnnotateMeta meta) {
        // copy原有参数
        Map<String, Object> argsMap = cloneArgsMap(meta);
        if (argsMap.isEmpty()) {
            return meta;
        }

        // 使用独立Meta
        DictType type = DictType.metaTypeOf(meta.getFqn());

        final List<AnnotatedParam> params = new ArrayList<>(4);
        // 加入from
        params.add(new AnnotatedParam("from", meta.getOwnerName()));
        switch (type) {
            case MAP -> {
                Object mapOf = argsMap.get("mapOf");
                AptUtil.throwIfAssert(null == mapOf,
                        "When DictType is 'MAP', [mapOf] must be specified");
                params.add(new AnnotatedParam("map", mapOf));
                meta.reset(MapField.class, params);
            }

            case ENUM -> {
                Object enumOf = argsMap.get("enumOf");
                AptUtil.throwIfAssert(null == enumOf,
                        "When DictType is 'ENUM', [enumOf] must be specified");
                params.add(new AnnotatedParam("type", enumOf));
                meta.reset(EnumField.class, params);
            }

            case SVC -> {
                Object group = argsMap.get("group");
                AptUtil.throwIfAssert(null == group,
                        "When DictType is 'SVC', [group] must be specified");

                params.add(new AnnotatedParam("group", group));
                meta.reset(SvcFiled.class, params);
            }

            case EXP -> {
                Object expr1 = argsMap.get("expr1");
                Object expr2 = argsMap.get("expr2");
                AptUtil.throwIfAssert(null == expr1 || null == expr2,
                        "When DictType is 'EXP', [expr1] and [expr2] must be specified");
                params.add(new AnnotatedParam("expr1", expr1));
                params.add(new AnnotatedParam("expr2", expr2));
                meta.reset(ExpField.class, params);
            }

            case BEAN -> {
                Object bean = argsMap.get("bean");
                AptUtil.throwIfAssert(null == bean,
                        "When DictType is 'BEAN', [bean] must be specified");
                params.add(new AnnotatedParam("bean", bean));
                meta.reset(BeanField.class, params);
            }
        }

        return meta;
    }

    @Override
    public Set<String> getHandleTypes() {
        return DictType.getMetaClassNames();
    }

}
